#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
天气服务模块
用于获取天气数据并判断是否适合跑步
"""

import urllib.request
import urllib.parse
import json
from datetime import datetime
import os
import sys

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src.config import (
    WEATHER_API_KEY,
    CITY,
    DATA_DIR,
    SUITABLE_TEMPERATURE_RANGE,
    SUITABLE_HUMIDITY_MAX,
    MAX_WIND_POWER
)

class WeatherService:
    """天气服务类"""
    
    def __init__(self, api_key=None, city=None, base_url='https://restapi.amap.com/v3/weather/weatherInfo'):
        """初始化天气服务
        
        Args:
            api_key (str): 高德地图API密钥，None时使用配置文件中的值
            city (str): 城市名称，None时使用配置文件中的值
            base_url (str): API基础URL
        """
        self.api_key = api_key if api_key is not None else WEATHER_API_KEY
        self.city = city if city is not None else CITY
        self.base_url = base_url
        self.data_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), DATA_DIR.lstrip('../'))
        os.makedirs(self.data_dir, exist_ok=True)
    
    def get_weather(self):
        """获取天气数据
        
        Returns:
            dict: 天气数据字典
        """
        try:
            # 如果提供了API密钥，则调用实际API
            if self.api_key:
                return self._fetch_weather_from_api()
            else:
                # 否则使用模拟数据
                print("未提供API密钥，使用模拟天气数据")
                return self._get_mock_weather_data()
        except Exception as e:
            print(f"获取天气数据时出错: {e}")
            return self._get_mock_weather_data()
    
    def _fetch_weather_from_api(self):
        """从API获取天气数据
        
        Returns:
            dict: 天气数据字典
        """
        # 构建查询参数
        params = urllib.parse.urlencode({
            'key': self.api_key,
            'city': self.city,
            'extensions': 'base',  # 获取基础天气信息
            'output': 'JSON'
        })
        
        # 构建完整的URL
        url = f"{self.base_url}?{params}"
        
        # 创建请求对象
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        })
        
        # 发送请求并获取响应
        try:
            with urllib.request.urlopen(req, timeout=10) as response:
                # 读取响应内容
                data = json.loads(response.read().decode('utf-8'))
                
                if data.get('status') == '1':
                    weather_info = data.get('lives', [{}])[0]
                    return {
                        'city': weather_info.get('city', self.city),
                        'temperature': float(weather_info.get('temperature', 25)),
                        'weather': weather_info.get('weather', '晴'),
                        'wind_direction': weather_info.get('winddirection', '无风向'),
                        'wind_power': weather_info.get('windpower', '1-2级'),
                        'humidity': int(weather_info.get('humidity', 60)),
                        'update_time': weather_info.get('reporttime', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
                    }
                else:
                    raise Exception(f"获取天气数据失败: {data.get('info', '未知错误')}")
        except urllib.error.URLError as e:
            raise Exception(f"网络错误: {str(e)}")
        except Exception as e:
            raise Exception(f"获取天气数据时出错: {str(e)}")
    
    def _get_mock_weather_data(self):
        """获取模拟天气数据
        
        Returns:
            dict: 模拟天气数据字典
        """
        # 根据当前时间生成不同的模拟天气
        hour = datetime.now().hour
        
        if 6 <= hour < 12:
            # 上午天气
            weather_conditions = [
                {'weather': '晴', 'temperature': 22, 'humidity': 55, 'wind_power': '1-2级'},
                {'weather': '多云', 'temperature': 20, 'humidity': 60, 'wind_power': '2-3级'}
            ]
            condition = weather_conditions[0]  # 默认使用第一种天气
        elif 12 <= hour < 18:
            # 下午天气
            weather_conditions = [
                {'weather': '晴', 'temperature': 28, 'humidity': 45, 'wind_power': '2-3级'},
                {'weather': '多云', 'temperature': 26, 'humidity': 50, 'wind_power': '1-2级'}
            ]
            condition = weather_conditions[0]  # 默认使用第一种天气
        else:
            # 晚上天气
            weather_conditions = [
                {'weather': '晴', 'temperature': 18, 'humidity': 65, 'wind_power': '1级'},
                {'weather': '多云', 'temperature': 17, 'humidity': 70, 'wind_power': '1-2级'}
            ]
            condition = weather_conditions[0]  # 默认使用第一种天气
        
        return {
            'city': self.city,
            'temperature': condition['temperature'],
            'weather': condition['weather'],
            'wind_direction': '东南风',
            'wind_power': condition['wind_power'],
            'humidity': condition['humidity'],
            'update_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
    
    def is_suitable_for_running(self, weather_data):
        """判断天气是否适合跑步
        
        Args:
            weather_data (dict): 天气数据字典
        
        Returns:
            tuple: (是否适合跑步, 建议)
        """
        # 从配置文件获取判断标准
        min_temp, max_temp = SUITABLE_TEMPERATURE_RANGE
        
        # 提取天气数据
        temperature = weather_data.get('temperature', 25)
        humidity = weather_data.get('humidity', 60)
        weather = weather_data.get('weather', '晴')
        wind_power = weather_data.get('wind_power', '1-2级')
        
        # 不适合跑步的天气
        unsuitable_weather = ['雨', '雪', '雷', '雾', '霾', '沙尘']
        if any(w in weather for w in unsuitable_weather):
            return False, f"当前天气为{weather}，不建议户外跑步"
        
        # 温度判断
        if temperature < 0 or temperature > 35:
            return False, f"当前温度为{temperature}°C，温度不适宜跑步"
        
        # 湿度判断
        if humidity > SUITABLE_HUMIDITY_MAX:
            return False, f"当前湿度为{humidity}%，湿度较大，不建议高强度跑步"
        
        # 风力判断
        # 提取风力等级数字
        import re
        wind_numbers = re.findall(r'\d+', wind_power)
        wind_level = int(wind_numbers[0]) if wind_numbers else 0
        
        if wind_level > MAX_WIND_POWER:
            return False, f"当前风力为{wind_power}，风力较大，不建议户外跑步"
        elif wind_level == MAX_WIND_POWER:
            return True, f"当前风力为{wind_power}，风力稍大，建议适当降低跑步强度"
        
        # 最适宜跑步的条件
        if min_temp <= temperature <= max_temp and humidity <= 65 and '晴' in weather:
            return True, "天气非常适合跑步，是运动的好时机！"
        
        # 其他情况
        return True, "天气条件适合跑步，注意适当补充水分"
    
    def save_weather_data(self, weather_data):
        """保存天气数据到JSON文件
        
        Args:
            weather_data (dict): 天气数据字典
        """
        filename = os.path.join(self.data_dir, f"weather_{datetime.now().strftime('%Y%m%d')}.json")
        try:
            # 如果文件已存在，读取现有数据
            if os.path.exists(filename):
                with open(filename, 'r', encoding='utf-8') as f:
                    existing_data = json.load(f)
            else:
                existing_data = []
            
            # 添加新数据
            existing_data.append({
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'data': weather_data
            })
            
            # 保存数据
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(existing_data, f, ensure_ascii=False, indent=2)
            
            print(f"天气数据已保存到 {filename}")
        except Exception as e:
            print(f"保存天气数据时出错: {e}")

if __name__ == '__main__':
    # 测试天气服务
    weather_service = WeatherService()
    weather_data = weather_service.get_weather()
    print("天气数据:")
    print(json.dumps(weather_data, ensure_ascii=False, indent=2))
    
    suitable, advice = weather_service.is_suitable_for_running(weather_data)
    print(f"\n是否适合跑步: {'是' if suitable else '否'}")
    print(f"建议: {advice}")
    
    weather_service.save_weather_data(weather_data)